package cn.com.blueInfo.bpm.template.repository.impl;

import cn.com.blueInfo.bpm.common.entity.BaseEntity;
import cn.com.blueInfo.bpm.common.enums.BaseDeleted;
import cn.com.blueInfo.bpm.common.repository.BaseRepository;
import cn.com.blueInfo.bpm.template.entity.ParallelGateway;
import cn.com.blueInfo.bpm.template.enums.ParallelGatewayType;
import cn.com.blueInfo.bpm.template.mapper.ParallelGatewayMapper;
import cn.com.blueInfo.bpm.template.repository.ParallelGatewayRepository;
import cn.com.blueInfo.bpm.template.request.ParallelGatewayDTO;
import cn.com.blueInfo.core.entity.CurrentLoginUserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 并行网关表 数据服务实现类
 * @author suxch
 * @since 2025-09-01 19:30:44
 */
@Log4j2
@Service
public class ParallelGatewayRepositoryImpl
        extends ServiceImpl<ParallelGatewayMapper, ParallelGateway>
        implements ParallelGatewayRepository, BaseRepository<ParallelGateway, ParallelGatewayDTO.QueryDTO> {

    @Autowired
    private CurrentLoginUserInfo currentLoginUserInfo;

    /**
     * 提供获取 CurrentLoginUserInfo 的方法（由实现类提供，避免接口中注入）
     * @return CurrentLoginUserInfo
     */
    @Override
    public CurrentLoginUserInfo getCurrentLoginUserInfo() {
        return currentLoginUserInfo;
    }

    /**
     * 新增并行网关
     * @param parallelGateway 并行网关参数
     */
    @Override
    public Integer createParallelGateway(ParallelGateway parallelGateway) {
        return sqlExecuteResult(save(parallelGateway));
    }

    /**
     * 批量新增并行网关
     * @param parallelGatewayList 并行网关参数批量
     */
    @Override
    public Integer batchCreateParallelGateway(List<ParallelGateway> parallelGatewayList) {
        return sqlExecuteResult(saveBatch(parallelGatewayList), parallelGatewayList.size());
    }

    /**
     * 删除并行网关
     * @param parallelGatewayId 并行网关ID
     */
    @Override
    public Integer deleteParallelGateway(Long parallelGatewayId) {
        ParallelGateway parallelGateway = new ParallelGateway();
        parallelGateway.setId(parallelGatewayId);
        parallelGateway.setDeleted(BaseDeleted.DELETED);
        return sqlExecuteResult(removeById(parallelGateway));
    }

    /**
     * 批量删除并行网关
     * @param parallelGatewayIdList 并行网关ID批量
     */
    @Override
    public Integer batchDeleteParallelGateway(List<Long> parallelGatewayIdList) {
        List<ParallelGateway> parallelGatewayList = new ArrayList<>();
        for (Long parallelGatewayId : parallelGatewayIdList) {
            ParallelGateway parallelGateway = new ParallelGateway();
            parallelGateway.setId(parallelGatewayId);
            parallelGateway.setDeleted(BaseDeleted.DELETED);
            parallelGatewayList.add(parallelGateway);
        }
        return sqlExecuteResult(removeBatchByIds(parallelGatewayList), parallelGatewayList.size());
    }

    /**
     * 更新部分并行网关
     * @param parallelGateway 并行网关参数
     */
    @Override
    public Integer updateParallelGatewayPartial(ParallelGateway parallelGateway) {
        validateUpdateId(parallelGateway.getId());
        LambdaUpdateWrapper<ParallelGateway> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ParallelGateway::getId, parallelGateway.getId());
        return sqlExecuteResult(update(updateWrapper));
    }

    /**
     * 更新全部并行网关
     * @param parallelGateway 并行网关参数
     */
    @Override
    public Integer updateParallelGateway(ParallelGateway parallelGateway) {
        validateUpdateId(parallelGateway.getId());
        return sqlExecuteResult(updateById(parallelGateway));
    }

    /**
     * 查询一条并行网关
     * @param parallelGatewayId 并行网关ID
     */
    @Override
    public ParallelGateway getParallelGatewayById(Long parallelGatewayId) {
        LambdaQueryWrapper<ParallelGateway> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParallelGateway::getId, parallelGatewayId);
        return getOne(queryWrapper);
    }

    /**
     * 分页查询并行网关
     * @param parallelGatewayQueryDTO 并行网关参数
     */
    @Override
    public Page<ParallelGateway> getParallelGatewayPage(ParallelGatewayDTO.QueryDTO parallelGatewayQueryDTO) {
        Page<ParallelGateway> parallelGatewayPage = new Page<>(
                parallelGatewayQueryDTO.getPage(), parallelGatewayQueryDTO.getSize());
        LambdaQueryWrapper<ParallelGateway> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, parallelGatewayQueryDTO);

        BaseDeleted deleted = parallelGatewayQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeletePage(parallelGatewayPage, queryWrapper);
        } else {
            return page(parallelGatewayPage, queryWrapper);
        }
    }

    /**
     * 根据条件查询 并行网关 数量
     * @param parallelGatewayQueryDTO 并行网关参数
     */
    @Override
    public Long getParallelGatewayCount(ParallelGatewayDTO.QueryDTO parallelGatewayQueryDTO) {
        LambdaQueryWrapper<ParallelGateway> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, parallelGatewayQueryDTO);

        BaseDeleted deleted = parallelGatewayQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteCount(queryWrapper);
        } else {
            return count(queryWrapper);
        }
    }

    /**
     * 根据条件查询 并行网关
     * @param parallelGatewayQueryDTO 并行网关参数
     */
    @Override
    public List<ParallelGateway> getParallelGatewayList(ParallelGatewayDTO.QueryDTO parallelGatewayQueryDTO) {
        LambdaQueryWrapper<ParallelGateway> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, parallelGatewayQueryDTO);

        BaseDeleted deleted = parallelGatewayQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteList(queryWrapper);
        } else {
            return list(queryWrapper);
        }
    }

    private void queryWrapper(LambdaQueryWrapper<ParallelGateway> queryWrapper,
                              ParallelGatewayDTO.QueryDTO parallelGatewayQueryDTO) {

        Long processId = parallelGatewayQueryDTO.getProcessId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(processId), ParallelGateway::getProcessId, processId);

        String gatewayCode = parallelGatewayQueryDTO.getGatewayCode();
        queryWrapper.eq(StringUtils.isNotBlank(gatewayCode), ParallelGateway::getGatewayCode, gatewayCode);

        String gatewayName = parallelGatewayQueryDTO.getGatewayName();
        queryWrapper.eq(StringUtils.isNotBlank(gatewayName), ParallelGateway::getGatewayName, gatewayName);

        ParallelGatewayType gatewayType = parallelGatewayQueryDTO.getGatewayType();
        queryWrapper.eq(ObjectUtils.isNotEmpty(gatewayType), ParallelGateway::getGatewayType, gatewayType);

        Long prevNodeId = parallelGatewayQueryDTO.getPrevNodeId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(prevNodeId), ParallelGateway::getPrevNodeId, prevNodeId);

        String joinCondition = parallelGatewayQueryDTO.getJoinCondition();
        queryWrapper.eq(StringUtils.isNotBlank(joinCondition), ParallelGateway::getJoinCondition, joinCondition);

        addQueryWrapper(queryWrapper, parallelGatewayQueryDTO, getCommonColumn());

    }

    private Map<String, SFunction<ParallelGateway, ?>> getCommonColumn() {
        return BaseEntity.getCommonColumn(
                ParallelGateway::getOrderNumber,
                ParallelGateway::getTenantId,
                ParallelGateway::getApplicationId,
                ParallelGateway::getStatus,
                ParallelGateway::getDeleted,
                ParallelGateway::getDeleteUserId,
                ParallelGateway::getDeleteTime,
                ParallelGateway::getRemark,
                ParallelGateway::getCreateUserId,
                ParallelGateway::getCreateTime,
                ParallelGateway::getUpdateUserId,
                ParallelGateway::getUpdateTime,
                ParallelGateway::getExtend1,
                ParallelGateway::getExtend2,
                ParallelGateway::getExtend3);
    }

}
